package com.mcxx.modules.miniSalvation.fundpay.service.write;

import com.google.common.collect.Lists;
import com.mcxx.common.exception.BizException;
import com.mcxx.modules.miniSalvation.fundpay.dao.write.SingleFundPayWriteDao;
import com.mcxx.modules.miniSalvation.fundpay.dto.SingleRollDTO;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayEntity;
import com.mcxx.modules.miniSalvation.fundpay.entity.SingleFundPayMemberEntity;
import com.mcxx.modules.miniSalvation.fundpay.service.read.SingleCommonService;
import com.mcxx.modules.miniSalvation.fundpay.service.read.SingleFundPayReadService;
import com.mcxx.result.BaseResult;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.mcxx.util.HttpServiceUtil;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("singleFundPayWriteService")
@TaTransactional
public class SingleFundPayWriteService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SingleFundPayWriteService.class);

    @Autowired
    private SingleFundPayWriteDao singleFundPayWriteDao;

    @Autowired
    private SingleFundPayReadService singleFundPayReadService;

    @Autowired
    private SingleFundPayExceptionWriteService singleFundPayExceptionService;

    @Autowired
    private SingleCommonService singleCommonService;


    public void updatePayRollInfo(String status, int houseNum, int members, Double fundNumber, String fundPayId) {
        singleFundPayWriteDao.updatePayRollInfo(status, houseNum, members, fundNumber, fundPayId);
    }

    public void saveMemberPayRollInfo(List<SingleFundPayMemberEntity> results) {
        List<List<SingleFundPayMemberEntity>> subList = Lists.partition(results, 1024);
        for (int i = 0; i < subList.size(); i++) {
            singleFundPayWriteDao.insertMemberPayRoll(subList.get(i));
        }
    }


    public FundPayEntity insertGrantRoll(SingleRollDTO singleRollDTO,
                                         UserAccountVo userAccountVo,
                                         String state) {
        singleRollDTO.setId(Constant.getUUID());
        singleRollDTO.setOrgId(userAccountVo.getOrgId());
        singleRollDTO.setAreaCode(userAccountVo.getAreaCode());
        FundPayEntity fundPayEntity = new FundPayEntity();
        BeanUtils.copyProperties(singleRollDTO, fundPayEntity);
        fundPayEntity.setStatus(state);

        fundPayEntity.setIsAuto(Constant.IsAuto.NO);
        fundPayEntity.setOperator(userAccountVo.getUserId());
        this.insert(fundPayEntity);
        return fundPayEntity;
    }


    public int insert(FundPayEntity fundPayEntity) {
        fundPayEntity.setCreateTime(new Date());
        int rst = singleFundPayWriteDao.insertIgnoreNull(fundPayEntity);
        if (rst <= 0) {
            throw new BizException(FailureCode.ERR_10043);
        }
        return rst;
    }


    public BaseResult<Map<String, List<String>>> delFundPay(List<String> fundPayIdList, String fundpayDelUrl) {
        BaseResult<Map<String, List<String>>> result = new BaseResult<>();

        List<String> stateList = new ArrayList<String>() {{
            add(Constant.FundPayState.CREATE);
            add(Constant.FundPayState.REVOKE);
            add(Constant.FundPayState.CREATE_FAIL);
        }};
        Map<String, List<String>> rstMap = singleFundPayReadService.getIdByIdAndStates(fundPayIdList, stateList);
        if (!rstMap.containsKey("success")) {

            return BaseResult.fail("名册还未确认");
        }


        for (String fundpayId : fundPayIdList) {
            String retMsg = HttpServiceUtil.httpCallDelFundpayData(fundpayDelUrl, fundpayId);
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(retMsg)) {
                return BaseResult.fail("同步删除发放系统名册失败:" + retMsg);
            }
        }


        singleFundPayWriteDao.deleteMemberByFundPayIds(rstMap.get("success"));


        int rst = singleFundPayWriteDao.deleteRollByIds(fundPayIdList);

        if (rst == 0) {

            rstMap.put("fail", fundPayIdList);
            rstMap.remove("success");
        } else {
            int count = singleFundPayExceptionService.deleteByFundPayId(fundPayIdList);
            LOGGER.info("删除名册相关的异常数据：{}", count);
        }
        result.setData(rstMap);
        return result;
    }



    public void confirmFundPay(String fundPayId, UserAccountVo userAccountVo) {
        FundPayEntity fundPayEntity = new FundPayEntity();
        fundPayEntity.setId(fundPayId);
        fundPayEntity.setStatus(Constant.FundPayState.CONFIRM);
        fundPayEntity.setCommitDate(new Date());
        fundPayEntity.setCheckPerson(userAccountVo.getUserId());
        int rst = singleFundPayWriteDao.updateIgnoreNull(fundPayEntity);
        if (rst <= 0) {
            throw new BizException("-1", "名册确认失败");
        }
    }


    public int updateStateByIds(List<String> fundPayIdList, String state, Date commitDate) {
        return singleFundPayWriteDao.updateStateByIds(fundPayIdList, state, commitDate);
    }


    public void insertFundPayRoll(SingleRollDTO singleRollDTO, UserAccountVo userAccountVo) {

        List<SingleFundPayMemberEntity> rollMembers = singleFundPayReadService.getCapitalStatRollDetail(singleRollDTO);


        if (singleRollDTO.getFundType().equals(Constant.FundType.STAND_FUND_PAY)) {

            this.insertGrantRoll(singleRollDTO, userAccountVo, Constant.FundPayState.CREATE_ING);
        }
        if (singleRollDTO.getFundType().equals(Constant.FundType.CUSTOM_FUND_PAY)) {

            this.insertGrantRoll(singleRollDTO, userAccountVo, Constant.FundPayState.CREATE);
        }

        singleCommonService.handleRollDetailData(singleRollDTO, rollMembers);
    }


    public void insertFundPayAllowanceRoll(SingleRollDTO singleRollDTO, UserAccountVo userAccountVo) {

        List<SingleFundPayMemberEntity> rollMembers = singleFundPayReadService.getFamilyStatRollDetail(singleRollDTO);


        this.insertGrantRoll(singleRollDTO, userAccountVo, Constant.FundPayState.CREATE_ING);


        singleCommonService.handleRollDetailData(singleRollDTO, rollMembers);
    }
}
